package com.ruicar.afs.jobadmin.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.jobadmin.core.model.AfsJobGroup;
import com.ruicar.afs.jobadmin.core.model.AfsJobInfo;
import com.ruicar.afs.jobadmin.core.model.AfsJobRegistry;
import com.ruicar.afs.jobadmin.dto.GroupDto;
import com.ruicar.afs.jobadmin.mapper.AfsJobInfoMapper;
import com.ruicar.afs.jobadmin.core.util.I18nUtil;
import com.ruicar.afs.jobadmin.mapper.AfsJobGroupMapper;
import com.ruicar.afs.jobadmin.mapper.AfsJobRegistryMapper;
import com.ruicar.afs.cloud.common.job.core.biz.model.ReturnT;
import com.ruicar.afs.cloud.common.job.core.enums.RegistryConfig;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * The type JobGroupController
 * <p>Description: </p>
 *
 * @author Fzero
 * @version 1.0
 * @date Created on 2020.06.13 14:17:13
 * @since 1.0
 */
@RestController
@RequestMapping("/jobgroup")
public class JobGroupController {

    /**
     * Afs job info mapper
     * <p>Description: </p>
     */
    @Resource
    public AfsJobInfoMapper afsJobInfoMapper;
    /**
     * Afs job group mapper
     * <p>Description: </p>
     */
    @Resource
    public AfsJobGroupMapper afsJobGroupMapper;
    /**
     * Afs job registry mapper
     * <p>Description: </p>
     */
    @Resource
    private AfsJobRegistryMapper afsJobRegistryMapper;

    /**
     * Index response
     *
     * @return the response
     */
    @PostMapping("/listAllGroup")
    public IResponse<List<AfsJobInfo>> index() {
        return IResponse.success(afsJobGroupMapper.findAll());
    }

    /**
     * List group response
     *
     * @param groupDto group dto
     * @return the response
     */
    @PostMapping("/list")
    public IResponse listGroup(@RequestBody GroupDto groupDto) {
       return IResponse.success(afsJobGroupMapper.selectPage(new Page(groupDto.getPageIndex(),groupDto.getPageSize()),
                Wrappers.<AfsJobGroup>lambdaQuery()
                .like(StringUtils.isNotEmpty(groupDto.getAppName()), AfsJobGroup::getAppName,groupDto.getAppName())
                .like(StringUtils.isNotEmpty(groupDto.getTitle()), AfsJobGroup::getTitle,groupDto.getTitle())
        ));
    }

    /**
     * Save response
     *
     * @param afsJobGroup afs job group
     * @return the response
     */
    @PostMapping("/save")
    public IResponse<String> save(@RequestBody AfsJobGroup afsJobGroup) {
        // valid
        if (afsJobGroup.getAppName() == null || afsJobGroup.getAppName().trim().length() == 0) {
            return IResponse.fail((I18nUtil.getString("system_please_input") + "应用名"));
        }
        if (afsJobGroup.getAppName().length() < 4 || afsJobGroup.getAppName().length() > 64) {
            return IResponse.fail(I18nUtil.getString("jobgroup_field_appName_length"));
        }
        if (afsJobGroup.getTitle() == null || afsJobGroup.getTitle().trim().length() == 0) {
            return IResponse.fail((I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
        }
        if (afsJobGroup.getAddressType() != 0) {
            if (afsJobGroup.getAddressList() == null || afsJobGroup.getAddressList().trim().length() == 0) {
                IResponse.fail(I18nUtil.getString("jobgroup_field_addressType_limit"));
            }
            String[] addresss = afsJobGroup.getAddressList().split(",");
            for (String item : addresss) {
                if (item == null || item.trim().length() == 0) {
                    IResponse.fail(I18nUtil.getString("jobgroup_field_registryList_unvalid"));
                }
            }
        }

        int ret = afsJobGroupMapper.save(afsJobGroup);
        return (ret > 0) ? IResponse.success("") : IResponse.fail("");
    }

    /**
     * Update response
     *
     * @param afsJobGroup afs job group
     * @return the response
     */
    @PostMapping("/update")
    public IResponse<String> update(@RequestBody AfsJobGroup afsJobGroup) {
        // valid
        if (afsJobGroup.getAppName() == null || afsJobGroup.getAppName().trim().length() == 0) {
            return IResponse.fail((I18nUtil.getString("system_please_input") + "应用名"));
        }
        if (afsJobGroup.getAppName().length() < 4 || afsJobGroup.getAppName().length() > 64) {
            return IResponse.fail(I18nUtil.getString("jobgroup_field_appName_length"));
        }
        if (afsJobGroup.getTitle() == null || afsJobGroup.getTitle().trim().length() == 0) {
            return IResponse.fail((I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")));
        }
        if (afsJobGroup.getAddressType() == 0) {
            // 0=自动注册
            List<String> registryList = findRegistryByAppName(afsJobGroup.getAppName());
            String addressListStr = null;
            if (registryList != null && !registryList.isEmpty()) {
                Collections.sort(registryList);
                addressListStr = "";
                for (String item : registryList) {
                    addressListStr += item + ",";
                }
                addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
            }
            afsJobGroup.setAddressList(addressListStr);
        } else {
            // 1=手动录入
            if (afsJobGroup.getAddressList() == null || afsJobGroup.getAddressList().trim().length() == 0) {
                IResponse.fail(I18nUtil.getString("jobgroup_field_addressType_limit"));
            }
            String[] addresss = afsJobGroup.getAddressList().split(",");
            for (String item : addresss) {
                if (item == null || item.trim().length() == 0) {
                    IResponse.fail(I18nUtil.getString("jobgroup_field_registryList_unvalid"));
                }
            }
        }

        int ret = afsJobGroupMapper.update(afsJobGroup);
        return (ret > 0) ? IResponse.success("") : IResponse.fail("");
    }

    /**
     * Find registry by app name list
     *
     * @param appNameParam app name param
     * @return the list
     */
    private List<String> findRegistryByAppName(String appNameParam) {
        HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
        List<AfsJobRegistry> list = afsJobRegistryMapper.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
        if (list != null) {
            for (AfsJobRegistry item : list) {
                if (RegistryConfig.RegistryType.EXECUTOR.name().equals(item.getRegistryGroup())) {
                    String appName = item.getRegistryKey();
                    List<String> registryList = appAddressMap.get(appName);
                    if (registryList == null) {
                        registryList = new ArrayList<String>();
                    }

                    if (!registryList.contains(item.getRegistryValue())) {
                        registryList.add(item.getRegistryValue());
                    }
                    appAddressMap.put(appName, registryList);
                }
            }
        }
        return appAddressMap.get(appNameParam);
    }

    /**
     * Remove response
     *
     * @param id id
     * @return the response
     */
    @GetMapping("/remove")
    public IResponse<String> remove(int id) {

        // valid
        int count = afsJobInfoMapper.selectCount(Wrappers.<AfsJobInfo>lambdaQuery().eq(AfsJobInfo::getJobGroup,id));
        if (count > 0) {
            return IResponse.fail(I18nUtil.getString("jobgroup_del_limit_0"));
        }

        List<AfsJobGroup> allList = afsJobGroupMapper.findAll();
        if (allList.size() == 1) {
            return IResponse.fail(I18nUtil.getString("jobgroup_del_limit_1"));
        }

        int ret = afsJobGroupMapper.remove(id);
        return IResponse.success("");
    }

    /**
     * Load by id return t
     *
     * @param id id
     * @return the return t
     */
    @RequestMapping("/loadById")
    @ResponseBody
    public ReturnT<AfsJobGroup> loadById(int id) {
        AfsJobGroup jobGroup = afsJobGroupMapper.load(id);
        return jobGroup != null ? new ReturnT<AfsJobGroup>(jobGroup) : new ReturnT<AfsJobGroup>(ReturnT.FAIL_CODE, null);
    }

}
